<template>
  <div>
    <!-- header -->
    <!-- 绑定子组件传递过来的事件和数据对象 -->
    <todo-header @addTodo="addTodo"></todo-header>
    <!-- todo列表 -->
    <!-- data => 向子组件传入data数据 -->
    <!-- toggleCompleted => 来自子组件传递的事件 -->
    <!-- removeTodo => 来自子组件传递的事件 -->
    <todos
      :data="todoList"
      @toggleCompleted="toggleCompleted"
      @removeTodo="removeTodo"
    ></todos>
    <!-- footer -->
    <todo-footer @removeAll="removeAll"></todo-footer>
  </div>
</template>

<script>
import TodoHeader from "./TodoHeader/index.vue";
import TodoFooter from "./TodoFooter/index.vue";
import Todos from "./Todos/index.vue";

export default {
  name: "TodoList",
  components: {
    TodoHeader,
    TodoFooter,
    Todos,
  },
  //提供属性
  //对象的写法存在问题1：不能直接拿到data里定义的属性
  // provide: {
  //   placeholder: this.placeholder,
  // },

  // 解决方案1：用函数的形式写provide
  // provide() {
  //   返回一个新的对象引用避免数据同时被修改
  //   return {
  //     placeholder: this.placeholder,
  //   };
  // },

  // 解决方案2：利用vue3.x组合式API
  //   provide() {
  //     return {
  //       placeholder: Vue.computed(() => this.placeholder),
  //       Vue.computed(() => this.placeholder)
  //       1.返回一个ComputedRefImpl对象
  //       2.ComputedRefImpl对象里的value属性对应placeholder的值
  //     };
  //   },

  /**
   * 解决方案3：
   * 在vue2.x中，在provide函数返回的对象里直接把vue实例传递过去`TodoListIns: this`，且在Inject的组件里写`inject: ["TodoListIns"]`，这里底下组件拿到的是整个组件vue实例 VueComponent{...}，而实例底下的placeholder属性就是拿到的值
   */
  provide() {
    return {
      //TodoListIns -> 实例
      //这里传入的实例里面的数据是响应式的(非常重要)
      TodoListIns: this,
    };
  },
  data() {
    return {
      todoList: [],
      placeholder: "请输入内容...",
    };
  },
  mounted() {
    //问题2：默认不会修改placeholder属性，没有数据响应式
    //因为vue2.x里明确表示少用provide/inject的方式穿透传递属性，而是通过父子间传递(遵从单向数据流体系)
    setTimeout(() => {
      this.placeholder = "Please input something...";
    }, 2000);
  },
  methods: {
    //来源于子组件的事件：点击添加组合数据到数组里保存
    //todo -> {id:xxx,content:xxx,complete:false}
    addTodo(todo) {
      this.todoList.push(todo);

      //每次添加完数据后 清空文本框输入的内容
    },
    //来源于子组件的事件：点击复选框改变当前项内容completed状态
    toggleCompleted(id) {
      //遍历所有项,修改符合项的内容
      this.todoList = this.todoList.map((item) => {
        if (item.id === id) {
          item.completed = !item.completed;
        }
        return item;
      });
    },
    //来源于子组件的事件：点击删除按钮删除当前项内容
    removeTodo(id) {
      //过滤掉 不符合条件 的那一项
      this.todoList = this.todoList.filter((item) => item.id !== id);
    },
    //来源于子组件的事件：点击全部删除按钮删除所有内容
    removeAll() {
      this.todoList = [];
    },
  },
};
</script>